package com.flow.engine.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.flow.engine.entity.FlowNodeTemplate;
import com.flow.engine.enums.standard.FlowAuditType;
import com.flow.engine.mapper.FlowNodeTemplateMapper;
import com.flow.engine.service.FlowNodeTemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class FlowNodeTemplateServiceImpl extends ServiceImpl<FlowNodeTemplateMapper, FlowNodeTemplate> implements FlowNodeTemplateService {

    @Autowired
    private FlowNodeTemplateMapper mapper;

    @Override
    public List<FlowNodeTemplate> queryFlowById(Long flowTemplateId) {
        List<FlowNodeTemplate> res = mapper.selectList(flowTemplateId);
        FlowNodeTemplate startNode = res.stream()
                .filter(node -> node.getParentIds() == null || node.getParentIds().isEmpty())
                .findFirst().orElse(null);
        initFlow(startNode, null, res);
        return res;
    }

    public void initFlow(FlowNodeTemplate node, FlowNodeTemplate parentNode, List<FlowNodeTemplate> nodes) {
        if (ObjectUtils.isEmpty(nodes)) {
            return ;
        }
        if (!ObjectUtils.isEmpty(parentNode)) {
            FlowAuditType nodeAuditType = node.getFlowAuditType();
            String flowNodeValue = node.getFlowAuditValue();
            switch (nodeAuditType) {
                case CHOSE -> flowNodeValue = getUserName(flowNodeValue);
                case DM -> flowNodeValue = getDeptManager(flowNodeValue, parentNode);
                case ROLE -> flowNodeValue = getCurrentLevelRole(flowNodeValue);
            }
            node.setFlowAuditValue(flowNodeValue);
        }
        List<Long> nextNodeIds = node.getNextIds();
        if (!CollectionUtils.isEmpty(nextNodeIds)) {
            List<FlowNodeTemplate> nextNodes = getNextNodes(nextNodeIds, nodes);
            nextNodes.forEach(n -> this.initFlow(n, node, nodes));
        }
    }

    private List<FlowNodeTemplate> getNextNodes(List<Long> nextNodeIds, List<FlowNodeTemplate> nodes) {
        return nodes.stream().filter(node -> nextNodeIds.contains(node.getId())).collect(Collectors.toList());
    }

    private String getUserName(String userId) {
        Map<String, String> map = new HashMap<>();
        map.put("userId", userId);
        map.put("userName", "userName");
        return JSON.toJSONString(map);
    }

    private String getDeptManager(String userId, FlowNodeTemplate parentNode) {
        String parentNodeDeptId = null;
        if (!ObjectUtils.isEmpty(parentNode.getParentIds())) {
            String flowNodeValue = parentNode.getFlowAuditValue();
            JSONObject flowNodeValueJson = JSON.parseObject(flowNodeValue);
            parentNodeDeptId = flowNodeValueJson.getString("deptId");
        }

        String res = parentNodeDeptId == null ? getDeptManagerByUserId(userId) : getDeptManagerByChildDeptId(parentNodeDeptId);
        Map<String, String> map = new HashMap<>();
        map.put("deptId", "deptId");
        map.put("userId", userId);
        map.put("userName", "userName");
        return JSON.toJSONString(map);
    }

    private String getDeptManagerByChildDeptId(String parentNodeDeptId) {
        return null;
    }

    private String getDeptManagerByUserId(String userId) {
        return null;
    }

    private String getCurrentLevelRole(String roleId) {
        Map<String, String> map = new HashMap<>();
        map.put("userId", "userId");
        map.put("userName", "userName");
        return JSON.toJSONString(map);
    }

}
